package com.simemg.reader.slice;

import com.simemg.reader.ResourceTable;
import com.simemg.reader.store.Book;
import com.simemg.reader.store.Page;
import com.simemg.reader.utils.*;
import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.content.Intent;
import ohos.agp.animation.Animator;
import ohos.agp.animation.AnimatorGroup;
import ohos.agp.animation.AnimatorProperty;
import ohos.agp.animation.AnimatorValue;
import ohos.agp.components.*;
import ohos.agp.render.Paint;
import ohos.agp.utils.Color;
import ohos.agp.window.dialog.CommonDialog;
import ohos.ai.tts.TtsClient;
import ohos.ai.tts.TtsListener;
import ohos.ai.tts.TtsParams;
import ohos.ai.tts.constants.TtsEvent;
import ohos.eventhandler.EventHandler;
import ohos.eventhandler.EventRunner;
import ohos.eventhandler.InnerEvent;
import ohos.utils.PacMap;

import java.util.*;

public class ListenSlice extends AbilitySlice {
    private Book book;
    private Page page;

    private Image image;
    private Text title;
    private static Text content;
    private Component listen;
    private Component next;
    private Component last;
    private Component setting;
    private Slider slider;

    private boolean isListen = false;
    private boolean isSetting = false;

    private static String[] lineList;
    private static int i = 0;

    private static final int EVENT_CREATE_SUCCESS = 0x0000001;
    private static final int EVENT_SPEECH_FINISH = 0x0000002;


    private float j = 0;
    AnimatorValue wa;

    private final TtsListener ttsListener = new TtsListener() {
        @Override
        public void onEvent(int eventType, PacMap pacMap) {
            if (eventType == TtsEvent.CREATE_TTS_CLIENT_SUCCESS) { handler.sendEvent(EVENT_CREATE_SUCCESS); }
        }
        @Override
        public void onStart(String utteranceId) {}
        @Override
        public void onProgress(String utteranceId, byte[] audioData, int progress) {}
        @Override
        public void onFinish(String utteranceId) {}
        @Override
        public void onSpeechStart(String utteranceId) {}
        @Override
        public void onSpeechProgressChanged(String utteranceId, int progress) {}
        @Override
        public void onSpeechFinish(String utteranceId) { handler.sendEvent(EVENT_SPEECH_FINISH); }
        @Override
        public void onError(String utteranceId, String errorMessage) {}
    };

    private final EventHandler handler = new EventHandler(EventRunner.current()) {
        @Override
        protected void processEvent(InnerEvent event) {
            switch (event.eventId) {
                case EVENT_CREATE_SUCCESS:
                    initTts();
                    break;
                case EVENT_SPEECH_FINISH:
                    readNextLine();
                    break;
                default:
                    break;
            }
        }
    };

    @Override
    public void onStart(Intent intent) {
        super.onStart(intent);
        super.setUIContent(ResourceTable.Layout_slice_listen);

        initComponent();
        loadData(intent);
        addComponentListen();
    }

    void initComponent() {
        image = (Image) findComponentById(ResourceTable.Id_img);
        title = (Text) findComponentById(ResourceTable.Id_title);
        content = (Text ) findComponentById(ResourceTable.Id_content);

        listen = findComponentById(ResourceTable.Id_listen);
        next = findComponentById(ResourceTable.Id_next);
        last = findComponentById(ResourceTable.Id_last);
        setting = findComponentById(ResourceTable.Id_setting);
        slider = (Slider) findComponentById(ResourceTable.Id_slider);


        TtsClient.getInstance().create(this, ttsListener);
    }

    void initTts() {
        TtsParams ttsParams = new TtsParams();
        ttsParams.setDeviceId(UUID.randomUUID().toString());
        TtsClient.getInstance().init(ttsParams);
    }

    void loadData(Intent intent) {
        int bookID = (Integer) RouterUtil.getData(intent);
        book = StoreUtil.searchBook(bookID);
        loadPage(book, book.getNowNum());
        RequestUtil.LoadImg(book.getImg()).setImage(image).setContext(getContext()).execute();
    }

    void addComponentListen() {
        listen.setClickedListener(component -> {
            if (!isListen) {
                TtsClient.getInstance().speakText(lineList[i], null);
            }
            else {
                TtsClient.getInstance().stopSpeak();
            }
            isListen = !isListen;
            component.setPressState(isListen);
        });
        next.setClickedListener(component -> {
            loadPage(book, book.getNowNum() + 1);
        });
        last.setClickedListener(component -> {
            loadPage(book, book.getNowNum() - 1);
        });
        setting.setClickedListener(component -> {
            Component layout = LayoutScatter.getInstance(this)
                    .parse(ResourceTable.Layout_component_dialog_setting, null, false);
            new CommonDialog(this)
                    .setContentCustomComponent(layout)
                    .setAutoClosable(true)
                    .setSize(AttrHelper.vp2px(250, this), AttrHelper.vp2px(300, this))
                    .show();

            Component speak1_layout = layout.findComponentById(ResourceTable.Id_speak1_layout);

            speak1_layout.addDrawTask((c, canvas) -> {
                Paint p = new Paint();
                p.setColor(new Color(Color.getIntColor("#FFDAE9D7")));
                p.setStrokeWidth(5f);
                p.setStyle(Paint.Style.STROKE_STYLE);
                canvas.drawCircle(c.getWidth()- AttrHelper.vp2px(50, getContext()),c.getHeight() / 2, AttrHelper.vp2px(40, getContext()) + j*100 , p);
                canvas.drawCircle(c.getWidth()- AttrHelper.vp2px(50, getContext()),c.getHeight() / 2, AttrHelper.vp2px(40, getContext()) + j*200 , p);
                canvas.drawCircle(c.getWidth()- AttrHelper.vp2px(50, getContext()),c.getHeight() / 2, AttrHelper.vp2px(40, getContext()) + j*300 , p);
                startAnimatorValue();
            }, Component.DrawTask.BETWEEN_BACKGROUND_AND_CONTENT);

            wa = new AnimatorValue();
            wa.setDuration(1500);
            wa.setLoopedCount(Animator.INFINITE);
            wa.setCurveType(Animator.CurveType.LINEAR);
            wa.setValueUpdateListener((animatorValue, vs) -> {
                j = vs;
                speak1_layout.invalidate();
            });
        });
    }

    void loadPage(Book book, int num) {
        i = 0;
        page = StoreUtil.readPage(book, num);
        if (page == null) return ;
        title.setText(page.getTitle());
        if (page.getCache() == null) {
            RequestUtil.Do(SpiderUtil.getSearchBookPage(page))
                    .onSuccess((RequestUtil.CallBackObject) (result)->{
                        String contentStr = (String) result;
                        StoreUtil.savePage(page, contentStr);
                        lineList = getLineList(contentStr);
                        content.setText(lineList[i]);
                        slider.setMaxValue(lineList.length);
                        slider.setProgressValue(i);
                    })
                    .execute();
        }
        else {
            lineList = getLineList(page.getContent());
            content.setText(lineList[i]);
            slider.setMaxValue(lineList.length);
            slider.setProgressValue(i);
        }

        tryLoadNextPage(book, num);
    }

    void tryLoadNextPage(Book book, int num) {
        if (book.getMaxNum() == num) return;
        Page nextPage = StoreUtil.searchPage(book, num + 1);
        if (nextPage != null && nextPage.getCache() == null) {
            RequestUtil.Do(SpiderUtil.getSearchBookPage(nextPage))
                    .onSuccess((RequestUtil.CallBackObject) (result)->{
                        String contentStr = (String) result;
                        if (contentStr != null) {
                            StoreUtil.savePage(nextPage, contentStr);
                        }
                    })
                    .execute();
        }
    }

    void readNextLine() {
        if (i == lineList.length - 1) {
            i = 0;
            loadPage(book, book.getNowNum() + 1);
        }
        else {
            i++;
        }
        slider.setProgressValue(i);
        content.setText(lineList[i]);
        TtsClient.getInstance().speakText(lineList[i], null);
    }

    String[] getLineList(String contentStr) {
        String[] result;
        result = contentStr.split("\n\n");
        if (result.length == 1) {
            result = contentStr.split("\n \n");
        }
        if (result.length == 1) {
            result = contentStr.split("\n");
        }
        return result;
    }

    public void startAnimatorValue() {
        if (wa.isRunning()) return;
        wa.start();
    }
}
